package NWish
{
	import NWish.Interface.IApp;
	
	public class SceneTree
	{
		private var _parent:IApp;
		public function get parent(){return _parent;}
		
		private var _window:Window;
		
		public function SceneTree(parent:IApp)
		{
			//
			_parent = parent;
			
			//
			var menuBar:MenuBar = _parent.getPlugin('MenuBar') as MenuBar;
			menuBar.windowMenu.addMenuItem("Scene &Tree").addActionListener(_showWindow);
			
			//
			_window = new Window(this);
			_window.show();
			
			//
			_parent.rootSprite.addEventListener(NWEvent.CREATE_OBJECT,	_window.onCreateObject);
			_parent.rootSprite.addEventListener(NWEvent.DELETE_OBJECT,	_window.onDeleteObject);
			_parent.rootSprite.addEventListener(NWEvent.CHANGE_PARENT,	_window.onChangeParent);
			_parent.rootSprite.addEventListener(NWEvent.CLEAR_SCENE,	_window.onClearScene,false,1);
		}
		
		public function init()
		{
			
		}
		
		private function _showWindow(e)
		{
			_window.show();
		}
		
	}
}



import NWish.Away3d;
import NWish.Interface.ILogger;
import NWish.Misc;
import NWish.NWEvent;
import NWish.SceneTree;

import away3d.cameras.Camera3D;
import away3d.containers.ObjectContainer3D;
import away3d.containers.Scene3D;
import away3d.containers.View3D;
import away3d.core.base.Object3D;
import away3d.entities.Entity;
import away3d.primitives.Cube;
import away3d.primitives.WireframeCube;
import away3d.primitives.WireframePrimitiveBase;
import away3d.primitives.WireframeSphere;

import flash.events.MouseEvent;

import org.aswing.*;
import org.aswing.border.*;
import org.aswing.colorchooser.*;
import org.aswing.event.AWEvent;
import org.aswing.ext.*;
import org.aswing.geom.*;
import org.aswing.tree.*;


class NWTreeNode extends DefaultMutableTreeNode
{
	public function NWTreeNode(userObject)
	{
		super(userObject,true);
		
		if(userObject is Object3D)
		{
			if(!userObject.extra)
				userObject.extra = new Object();
			
			userObject.extra.treeNode = this;
		}
	}
	
	override public function toString():String
	{
		var s:String = '';
		if (getUserObject() == null)
		    return null;
		else if(getUserObject() is Object3D)
		{
		    s = getUserObject().toString() + ' ' + getUserObject().name;
			
			s = s.replace('object','');
			s = s.replace('[ ','');
			s = s.replace(']',' : ');
			

			//
			if(getUserObject().hasOwnProperty('visible'))
			{
				if(getUserObject().visible == false)
					s += "       Hide";
				else
					s += "    Visible";
			}
			
			if(getUserObject().hasOwnProperty('mouseEnabled'))
			{
				if(getUserObject().mouseEnabled == false)
					s += "    Lock";
			}

		}
		else
		{
			s = getUserObject().toString();
			
			s = s.replace('object','');
			s = s.replace('[ ','');
			s = s.replace(']','');
		}
		
		return s;
    }
}

class Window extends JFrame
{
	private var _parent			:SceneTree;
	
	//members define
	private var _tree:JTree;
	
	
	public function Window(parent:SceneTree)
	{
		//
		_parent = parent;
		
		//
		super(null,'Scene Tree');
		
		
		//
		setLocationXY(0,15);
		setSize(new IntDimension(265, 640));
		
		//
		var panel:JPanel = new JPanel();
		panel.setSize(new IntDimension(250, 600));
		setContentPane(panel);
		
		//component creation
		var layout0:EmptyLayout = new EmptyLayout();
		panel.setLayout(layout0);
		
		
		//
		_tree = new JTree(createTreeNodes());
		//_tree.setLocation(new IntPoint(5, 5));
		//_tree.setSize(new IntDimension(366, 578));
		var sp = new JScrollPane(_tree);
		sp.setLocation(new IntPoint(5, 20));
		sp.setSize(new IntDimension(400, 650));
		panel.append(sp);
		
		var select:JButton = new JButton('select');
		var multiApply:JButton = new JButton('multi apply');
		//var copyName:JButton = new JButton('copy name');
		var visible:JButton = new JButton('visible');
		var lock:JButton = new JButton('lock');
		var delete_:JButton = new JButton('delete');
		//var properties:JButton = new JButton('    properties    ');
		//var visible:JButton = new JButton('visible');
		//var mouseEnable:JButton = new JButton('mouse enable');
		
		Misc.pack_list([select,multiApply,visible,lock,delete_],0,2);
		
		panel.append(select);
		panel.append(multiApply);
		panel.append(visible);
		panel.append(lock);
		panel.append(delete_);
		
		select.addActionListener(onSelect);
		multiApply.addActionListener(onMultiApply);
		visible.addActionListener(onVisible);
		lock.addActionListener(onLock);
		delete_.addActionListener(onDelete);
		//visible.addActionListener(onVisible);
		//mouseEnable.addActionListener(onMouseEnable);
		
		
		//
		_tree.addEventListener(MouseEvent.CLICK,onClick);
		//_tree.addSelectionListener(onSelectionListener);
	}
	
	public function get scene()
	{
		var away3d = _parent.parent.getPlugin('Away3d');
		
		if(away3d.view)
			return away3d.view.scene;
		
		return null;
	}
	
	public function get view()
	{
		return _parent.parent.getPlugin('Away3d').view;
	}
	
	var _viewNode:NWTreeNode;
	var _sceneNode:NWTreeNode;
	private function createTreeNodes()
	{
		if(view)
		{
			_viewNode = new NWTreeNode(view);
			
			_sceneNode = createObjectNode(view.scene);
			_viewNode.append(_sceneNode);
			
			var cn:NWTreeNode = new NWTreeNode(view.camera);
			view.camera.extra.treeNode = cn;
			_viewNode.append(cn);
			
			//
			return new DefaultTreeModel(_viewNode);
		}
		
		return new DefaultTreeModel(null);
	}
	
	private function createObjectNode(parent):NWTreeNode
	{
		var pn:NWTreeNode = new NWTreeNode(parent);
		
		
		//
		var num = parent.numChildren;
		for(var i = 0; i < num; ++i)
		{
			var c : ObjectContainer3D = parent.getChildAt(i);
			
			var cn:NWTreeNode = createObjectNode(c);
			
			pn.append(cn);
		}
		
		
		//
		return pn;
	}
	
	private function createOneObjectNode(obj)
	{
		if(obj is View3D)
		{
			_tree.setModel(createTreeNodes());
		}
		else if(obj is ObjectContainer3D)
		{
			var on = new NWTreeNode(obj);
			
			if(obj.parent == null || obj.parent.parent == null)//this parent is Scene3D._sceneGraphRoot
			{
				_sceneNode.append(on);
			}
			else
			{
				if(obj.parent.extra == null)
					throw new Error();
					//obj.parent.extra = new Object();
				
				if(!obj.parent.extra['treeNode'])
					obj.parent.extra['treeNode'] = _sceneNode;
				
				if(obj.parent.extra.treeNode)
					obj.parent.extra.treeNode.append(on);
			}
		}
		else
		{
			//throw new Error();
			ILogger.log('cannot handle this object in SceneTree!',obj);
		}

		if(visible)
			_tree.updateUI();
	}
	
	private function deleteOneObjectNode(obj:ObjectContainer3D)
	{
		if(obj is Camera3D
		&& obj.name == Away3d.SystemCamera)
			return;
		
		if(obj.name.search(Away3d.SysIcon3d1) != -1)
		{
			return;
		}
		
		if(obj.name.search(Away3d.SysIcon3d) != -1)
		{
			throw new Error();//test
			return;
		}
		
		if(obj.extra && obj.extra.treeNode)
		{
			obj.extra.treeNode.removeFromParent();
			delete obj.extra.treeNode;
		}
	}

	public function onCreateObject(e:NWEvent)
	{
		if(e.objects is Array)
			for each (var o in e.objects)
				createOneObjectNode(o);
		else
			createOneObjectNode(e.objects);
	}
	
	public function onDeleteObject(e:NWEvent)
	{
		if(e.objects is Array)
			for each (var o in e.objects)
				deleteOneObjectNode(o);
		else
			deleteOneObjectNode(e.objects);
		
		
		if(visible)
			_tree.updateUI();
	}
	
	public function onChangeParent(e:NWEvent)
	{
		if(e.objects is Array)
			throw new Error();
		else
		{
			var o = e.objects;
			if(o.extra && o.extra.hasOwnProperty('treeNode'))
			{
				o.extra.treeNode.removeFromParent();
				
				if(o.parent.extra == null && e.objects1 is Scene3D)
				{
					_sceneNode.append(o.extra.treeNode);
				}
				else
				{
					o.parent.extra.treeNode.append(o.extra.treeNode);
				}
				
				if(visible)
					_tree.updateUI();
			}
			else//创建obj时,就指定parent,这时不做处理,在调用这函数createOneObjectNode时会自动设置
			{
				
			}
		}
	}
	
	public function onClearScene(e:NWEvent)
	{
		if(scene == null)
			return;
	
		var arr = [];
		Misc.getChildrenByNameInScene(null,scene,arr);
		for each(var o in arr)
		{
			if(o is WireframePrimitiveBase)
				continue;
				
			deleteOneObjectNode(o);
		}
		
		_viewNode.removeFromParent();
		_sceneNode.removeFromParent();
		view.camera.extra.treeNode.removeFromParent();
		delete view.camera.extra.treeNode;
		
		
		if(visible)
			_tree.updateUI();
	}
	
	//
	private function _getSelectionObject()
	{
		var s = _tree.getLastSelectedPathComponent();
		return s.getUserObject();
	}
	
	
	private function _getSelectionObjects(_class = null)
	{
		if(_tree.getSelectionCount() == 1)
		{
			var o = _getSelectionObject();
			if(_class && o is _class)
				return [o];
			else if(!_class)
				return [o];
		}
		else if(_tree.getSelectionCount() > 1)
		{
			var ss = _tree.getSelectionPaths();
			var slist = [];
			for each(var s:TreePath in ss)
			{
				var o = s.getLastPathComponent().getUserObject()
				if(_class && o is _class)
					slist.push(o);
				else if(!_class)
					slist.push(o);
			}
			
			if(slist.length)
				return slist;
		}
	}
	private function onSelect(e)
	{
		if(_tree.getSelectionCount())
			_parent.parent.dispatchEvent(new NWEvent(NWEvent.SELSCT_OBJECT,_getSelectionObjects()))
	}
	private function onMultiApply(e)
	{
		if(_tree.getSelectionCount())
			_parent.parent.dispatchEvent(new NWEvent(NWEvent.MULTI_APPLY,_getSelectionObjects()))
	}
	
	private function onVisible(e)
	{
		if(_tree.getSelectionCount() == 1)
		{
			var obj = _getSelectionObject();
			
			if(obj && obj.hasOwnProperty('visible'))
				obj.visible = !obj.visible;
		}
		else if(_tree.getSelectionCount() > 1)
		{
			var objs = _getSelectionObjects(Object3D);
			for each(var obj in objs)
			{
				if(obj && obj.hasOwnProperty('visible'))
					obj.visible = !obj.visible;
			}
		}
		
		if(visible)
			_tree.updateUI();
	}
	private function onLock(e)
	{
		if(_tree.getSelectionCount() == 1)
		{
			var obj = _getSelectionObject();
			
			if(obj && obj.hasOwnProperty('mouseEnabled'))
				obj.mouseEnabled = !obj.mouseEnabled;
		}
		else if(_tree.getSelectionCount() > 1)
		{
			var objs = _getSelectionObjects(Object3D);
			for each(var obj in objs)
			{
				if(obj && obj.hasOwnProperty('mouseEnabled'))
					obj.mouseEnabled = !obj.mouseEnabled;
			}
		}
		
		if(visible)
			_tree.updateUI();
	}
	
	private function onDelete(e)
	{
		if(_tree.getSelectionCount())
		{
			var os = _getSelectionObjects();
			
			var deletes = [];
			for each(var o in os)
			{
				if(o is Camera3D && o.name == Away3d.SystemCamera)
				{
					ILogger.log('can not delete this camera',o);
				}
				else if(o is Object3D)
				{
					deletes.push(o);
				}
				else
				{
					ILogger.log('can not delete this object',o);
				}
			}
			
			if(deletes.length > 0)
				_parent.parent.dispatchEvent(new NWEvent(NWEvent.DELETE_OBJECT,deletes))
		}
	}
	
	private var _clickObject;
	private function onClick(e)
	{
		if(_tree.getSelectionCount() == 1)
		{
			var o = _getSelectionObject();
			if(o && o is Object3D && _clickObject == o)
				_parent.parent.getPlugin('CameraHDController').target = o.position;
			
			_clickObject = o;
		}
		else
		{
			_clickObject = null;
		}
	}
	
	/*private function onProperties(e)
	{
		var s = _tree.getLastSelectedPathComponent();
		if(s)
			_parent.parent.getPlugin('PropertiesExplorer').currObject = s.getUserObject();
	}*/

	
	
}



/*

private function onCopyName(e)
{
var str = '';
if(_tree.getSelectionCount() == 1)
{
var obj = _getSelectionObject();

if(obj && obj as Object3D)
str += obj.name;
else
str += obj;

}
else if(_tree.getSelectionCount() > 1)
{
var objs = _getSelectionObjects();
for each(var obj in objs)
{
if(str.length)
str += ', ';

if(obj && obj as Object3D)
str += obj.name;
else
str += obj;
}
}


Clipboard.generalClipboard.clear();
Clipboard.generalClipboard.setData(ClipboardFormats.TEXT_FORMAT, str);
}
*/



